package mc.contents.etc;

import com.alibaba.fastjson.JSON;
import com.taobao.api.domain.Shop;
import com.taobao.api.domain.User;
import mc.contents.dao.ShopInfoMapper;
import mc.contents.dao.UserInfoMapper;
import mc.contents.pojo.persistence.ShopInfo;
import mc.contents.web.CrawConfig;
import mc.contents.web.request.Args;
import mc.contents.web.request.Task;
import mc.contents.web.request.TaskParams;
import mc.support.service.common.ITaobaoTopAPIService;
import mc.support.taobao.api.GetSellerReq;
import mc.support.taobao.api.fields.GetSellerFields;
import mc.support.taobao.api.fields.GetShopInfoFields;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by LuoHui on 15-1-31.
 */
@Component
public class CrawHandler {
    private static Logger log = LoggerFactory.getLogger(CrawHandler.class);
    @Autowired
    private ShopInfoMapper shopInfoMapper;
    @Autowired
    private ITaobaoTopAPIService taobaoTopAPIService;
    @Autowired
    private CrawConfig crawConfig;
    @Autowired
    private UserInfoMapper userInfoMapper;

    private ExecutorService es = Executors.newFixedThreadPool(8);

    public void crawShopUrl( String nick ) {
        ShopInfo shopInfo = shopInfoMapper.getSidByNick( nick );
        if(shopInfo.getSid()==null || shopInfo.getSid()==14L){
            crawShopSid( shopInfo );
        }
        if( shopInfo.getSid()!=null ){
            crawUrl( shopInfo );
        }else{
            log.error("{}  sid is still null", shopInfo.getNick());
        }
    }

    public void crawShop4C( final ShopInfo shopInfo ) {
        es.execute(new Runnable() {
            @Override
            public void run() {
                crawShop4C0( shopInfo );
            }
        });
    }

    private void crawShop4C0( ShopInfo shopInfo ) {
        try{
            List<Task> taskList = new ArrayList<>( 1 );
            Task task = buildTaskList3(shopInfo);
            if(task!=null){
                taskList.add( task );
                sendCrawRequest( "SHOP_4C_CRAWL",taskList );
            }
        }catch ( Exception e ){
            e.printStackTrace();
        }
    }

    public void crawDsr( final ShopInfo shopInfo ) {
        es.execute(new Runnable() {
            @Override
            public void run() {
                crawDsr0(shopInfo );
            }
        });
    }

    private void crawDsr0( ShopInfo shopInfo ) {
        try{
            List<Task> taskList = new ArrayList<>( 1 );
            Task task = buildTaskList( shopInfo );
            if(task!=null){
                taskList.add( task );
                sendCrawRequest( "DSR_INFO_CRAW", taskList );
            }
        }catch ( Exception e ){
            e.printStackTrace();
        }
    }

    private void crawUrl( ShopInfo shopInfo ) {
        List<Task> tasks = new ArrayList<>( 1 );
        Task task = buildTaskList2( shopInfo );
        if(task!=null){
            tasks.add( task );
            String shopType = shopInfo.getShopType();
            if(shopType==null){
                User u =  taobaoTopAPIService.getSeller( shopInfo.getSessionKey(),new GetSellerReq().fields( new GetSellerFields().type() ) );
                if(u!=null){
                    shopType = u.getType();
                    shopInfo.setShopType( shopType );
                    userInfoMapper.updateUserType( shopInfo.getNick(),u.getType() );
                }else{
                    log.error( "{} getSeller is null",shopInfo.getNick() );
                }
            }
            String configName = !"C".equals( shopType ) ? "SHOP_URL_CRAW_TMALL" : "SHOP_URL_CRAW_TAOBAO";
            sendCrawRequest( configName, tasks );
        }
    }

    private Task buildTaskList( ShopInfo shopInfo ) {
        try {
            if(shopInfo.getDt()==null || shopInfo.getMainCategoryName()==null || new Date(  ).getDate()!=shopInfo.getDt().getDate()){
                if(shopInfo.getShopUrl()!=null){
                    System.out.println(shopInfo.getNick()+"url was craw , begin dsr");
                    Args args = new Args();
                    args.setUrl( "http://rate.taobao.com/user-rate-"+shopInfo.getShopUrl()+".htm" );
                    args.setId( URLEncoder.encode( shopInfo.getNick(), "UTF-8" ) );
                    args.setCallbackUrl( crawConfig.getCallbackUrl() + "dsrResponse" );
                    String hook = "function(args,result){return{url:args.callbackUrl+\"?nick=\"+args.id,data:\"specialService=\"+result.specialService+\"&highOpinionRate=\"+result.highOpinionRate+\"&score=\"+(result.score||[]).join(',')+\"&mainCategory=\"+(result.mainCategory||[]).join(',')};}";
                    args.setHook(hook);
                    Task task = new Task();
                    task.setArgs( args );
                    return task;
                }
            }
        } catch ( Exception e ) {
            e.printStackTrace();
        }
        return null;
    }

    private Task buildTaskList2( ShopInfo shopInfo ) {
        try {
            Args args = new Args();
            args.setDebug( "false" );
            args.setUrl( "http://shop"+shopInfo.getSid()+".taobao.com" );
            args.setId( URLEncoder.encode(shopInfo.getNick(), "UTF-8") );
            args.setCallbackUrl( crawConfig.getCallbackUrl() + "shopUrlResponse" );
            String hook = "function(args,result){return{url:args.callbackUrl+\"?nick=\"+args.id,data:\"shopUrl=\"+result.shopUrl};}";
            args.setHook(hook);

            Task task = new Task();
            task.setArgs( args );
            return task;
        } catch ( Exception e ) {
            e.printStackTrace();
        }
        return null;
    }

    private Task buildTaskList3( ShopInfo shopInfo ) {
        try {
            Args args = new Args();
            args.setDebug( "false" );
            args.setUrl( "http://rate.taobao.com/ShopService4C.htm?userNumId="+shopInfo.getShopUrl()+"&ua&shopID="+shopInfo.getSid()+"&isB2C="+("C".equalsIgnoreCase(shopInfo.getShopType()) ? "false" : "true" ) );
            args.setId( URLEncoder.encode( shopInfo.getNick(), "UTF-8" ) );
            args.setCallbackUrl( crawConfig.getCallbackUrl() + "shop4CResponse" );
            String hook = "function(args,result){return{url:args.callbackUrl+\"?nick=\"+args.id,data:\"shop4C=\"+result.shop4C};}";
            args.setHook(hook);

            Task task = new Task();
            task.setArgs( args );
            return task;
        } catch ( Exception e ) {
            e.printStackTrace();
        }
        return null;
    }

    private void crawShopSid( ShopInfo shopInfo ) {
        Shop shop = taobaoTopAPIService.getShopInfo( shopInfo.getSessionKey(), shopInfo.getNick(), new GetShopInfoFields().sid().cid() );
        if(shop!=null){
            shopInfo.setSid( shop.getSid() );
            userInfoMapper.updateCidAndSid( shopInfo.getNick(),shop.getCid(),shop.getSid() );
        }else{
            log.error("{}  taobao shop but null", shopInfo.getNick() );
        }
    }

    private void sendCrawRequest( String configName,List<Task> taskList ){
        TaskParams taskJson = new TaskParams();
        taskJson.setConf( configName );
        taskJson.setUser( crawConfig.getUser() );
        taskJson.setKey( crawConfig.getKey() );
        taskJson.setTimeout( crawConfig.getCrawClientTimeOut() );
        taskJson.setTasks( taskList );

        String taskStr = JSON.toJSONString(taskJson);
        RestTemplate template = new RestTemplate(  );
        String response = template.postForObject( crawConfig.getApiUrl(), taskStr, String.class );
        log.info( " template post return {} ",response );
    }
}
